const Service = require("egg").Service;
const axios = require('axios');

// 通过群添加好友的接口已经失效
class GroupfriendsService extends Service {
  async create(ownerWxid, typename, groupwxid, content) {
    const { ctx } = this;

    const resGflist = await ctx.model.Groupfriends.find({ ownerWxid, groupwxid });
    
    // 步骤2：批量检查数据库中的重复
    const existingRecords = await ctx.model.Groupfriends.find({
      ownerWxid,
      groupwxid: { $in: resGflist },
    });
  }

  async delGroupfriend(_id) {
    const { ctx } = this;
    try {
      const result = await ctx.model.Groupfriends.deleteOne({ _id });

      if (result.deletedCount === 0) {
        return {
          code: 50000,
          msg: "数据库中未找到数据记录",
          data: null,
        };
      }
    } catch (error) {
      this.logger.error("删除失败:", error.message);
      return {
        code: 50000,
        msg: error.message || "删除失败，请检查网络或接口状态",
        data: null,
      };
    }
  }

  async getGroupfriend(ownerWxid, field, page, pageSize) {
    const { ctx } = this;
    try {
      // 构建查询条件
      let query = { ownerWxid };

      // 处理查询参数
      if (field.istask !== undefined) {
        query.istask = field.istask;
      }
      if (field.isok !== undefined) {
        query.isok = field.isok;
      }
      // 计算跳过的文档数量
      const skip = (page - 1) * pageSize;

      // 获取总数
      const total = await ctx.model.Groupfriends.countDocuments(query);

      // 使用 skip 和 limit 实现分页查询
      const data = await ctx.model.Groupfriends.find(query)
        .skip(skip)
        .limit(pageSize)
        .sort({
          createTime: -1, // 其次按创建时间降序
        })
        .exec();
      return {
        code: 20000,
        msg: "获取成功",
        data: {
          count: total,
          list: data,
        },
      };
    } catch (error) {
      // 捕获异常并返回错误信息
      this.logger.error("获取失败:", error.message);
      return {
        code: 50000,
        msg: "请求失败，请检查网络或接口状态",
        data: {
          count: 0,
          list: [],
        },
      };
    }
  }

  async editGroupfriend(id, record) {
    const { ctx } = this;
    return await ctx.model.Groupfriends.updateOne({ _id: id }, record);
  }

  async resetGroupfriend(id) {
    const { ctx } = this;
    return await ctx.model.Groupfriends.updateOne(
      { _id: id },
      {
        istask: false,
        isok: false,
        triggerTime: null,
      }
    );
  }

  /**
   * 异步为所有所有者的任务分配触发时间
   *
   * 此函数的目的是为每个所有者分配任务触发时间，仅处理未完成且未分配任务的时间记录
   * 它首先获取所有唯一的 ownerWxid，然后为每个所有者生成触发时间，并更新数据库中的任务记录
   *
   * @returns {Promise<Object>} 返回一个对象，包含分配任务的结果
   */
  async assignTriggerTimesForAllOwners() {
    const { ctx } = this;

    // 获取所有唯一的 ownerWxid
    const ownerWxids = await ctx.model.Groupfriends.distinct("ownerWxid", {
      isok: false,
      istask: false,
    });

    const results = [];

    // 对每个 ownerWxid 单独处理
    for (const ownerWxid of ownerWxids) {
      // 查询当前 owner 的未完成任务
      const tasks = await ctx.model.Groupfriends.find({
        ownerWxid,
        isok: false,
        istask: false,
      });

      const count = tasks.length;
      if (count === 0) continue; // 跳过无任务的 owner

      const step = 20; // 触发间隔（分钟）
      let startDate = new Date();

      // 获取该用户已有的最大 triggerTime
      const latestTime = await ctx.service.groupfriends.getLatestTriggerTimeByOwner(
        ownerWxid
      );
      if (latestTime) {
        startDate = new Date(latestTime);
      }

      // 生成触发时间
      const times = await ctx.service.groupfriends.assignTriggerTimes(
        startDate,
        count,
        step
      );

      // 批量更新任务
      const updatePromises = tasks.map(async (task, i) => {
        // 获取群好友nick
        const getNick = await ctx.service.wxchatroomdb.getMemberNick(task.ownerWxid, task.groupwxid, task.friendwxid)

        return ctx.model.Groupfriends.findByIdAndUpdate(
          task._id,
          {
            $set: {
              triggerTime: times[i],
              istask: true,
              nick: getNick,
            },
          },
          { new: true }
        );
      });

      try {
        const updatedRecords = await Promise.all(updatePromises);
        results.push({
          ownerWxid,
          count,
          updatedRecords,
          times: times.map((t) => t.toISOString()),
        });
      } catch (error) {
        this.ctx.logger.error(`分配任务给用户 ${ownerWxid} 时出错：`, error);
      }
    }

    return {
      code: 200,
      message: `成功为多个用户分配任务`,
      data: results,
    };
  }

  /**
   * 异步分配触发时间
   * 从指定的开始日期起，在有效时间内（09:00 - 23:59）生成一系列时间点
   * 主要用于需要在特定时间段内分配任务或事件的场景
   *
   * @param {Date} startDate 开始日期时间
   * @param {number} count 需要生成的时间点数量
   * @param {number} step 每个时间点之间的间隔（以分钟为单位）
   * @returns {Promise<Array<Date>>} 返回一个Promise，解析为一个包含生成时间点的数组
   */
  async assignTriggerTimes(startDate, count, step) {
    // 初始化当前时间为传入的开始日期时间
    const now = startDate;
    // 初始化时间槽数组，用于存储生成的时间点
    const slots = [];
    // 计算步长对应的毫秒数，便于后续时间计算
    const interval = step * 60 * 1000; // step分钟的毫秒数

    // 设置当前时间到有效范围（如果不在9:00-23:59内）
    let current = new Date(now);
    const hours = current.getHours();
    const minutes = current.getMinutes();

    // 如果早于9:00，设置为当天9:00
    if (hours < 9 || (hours === 9 && minutes < 0)) {
      current.setHours(9, 0, 0, 0);
    }
    // 如果晚于23:59，设置为第二天9:00
    else if (hours >= 23 && minutes >= 59) {
      current.setDate(current.getDate() + 1);
      current.setHours(9, 0, 0, 0);
    }

    // 生成时间点
    while (slots.length < count) {
      const slotHours = current.getHours();
      const slotMinutes = current.getMinutes();

      // 检查是否在有效时间范围内（09:00 - 23:59）
      if (slotHours >= 9 && !(slotHours === 23 && slotMinutes > 59)) {
        // ✅ 增加 8 小时5分钟 后再 push
        // 将当前时间点转换为北京时间（+8小时）并增加5分钟，然后添加到时间槽数组中
        const beijingTime = new Date(
          current.getTime() + 8 * 60 * 60 * 1000 + 300000
        );
        slots.push(beijingTime);
      }

      // 增加 step 分钟
      current.setTime(current.getTime() + interval);

      // 如果超过23:59，跳到第二天9:00
      if (current.getHours() >= 23 && current.getMinutes() > 59) {
        current.setDate(current.getDate() + 1);
        current.setHours(9, 0, 0, 0);
      }
    }

    // 返回生成的时间点数组
    return slots;
  }

  /**
   * 根据 ownerWxid 获取最新的触发时间
   * @param {string} ownerWxid - 微信用户ID
   * @returns {Promise<Date|null>} 最新的触发时间或者 null
   */
  async getLatestTriggerTimeByOwner(ownerWxid) {
    const { ctx } = this;

    const result = await ctx.model.Groupfriends.aggregate([
      {
        $match: {
          ownerWxid,
          istask: true,
        },
      },
      {
        $group: {
          _id: null,
          maxTime: { $max: "$triggerTime" },
        },
      },
    ]);

    return result.length > 0 && result[0].maxTime ? result[0].maxTime : null;
  }

  async editGroupfriendfromFwxid(ownerWxid, v3, field) {
    const { ctx } = this;
    try {
      const result = await ctx.model.Groupfriends.findOneAndUpdate(
        { ownerWxid,v3 },
        { $set: field },
        { new: true }
      );
      if (!result) {
        throw new Error("editPhonefromFwxid，自动更新状态 未找到数据");
      }
      return result;
    } catch (error) {
      this.logger.error("更新失败:", error);
      throw error;
    }
  }
}

module.exports = GroupfriendsService;
